package com.fuint.utils.syb;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonAlias;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TreeMap;

import static com.fuint.utils.syb.SybPayUtils.getAppKey;
import static com.fuint.utils.syb.SybUtil.parseEntity;

/**
 * 云闪付
 *
 * @author Tom
 * @since 2025-02-19
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SybYunPayDTO implements SybBaseDTO {
    @JsonAlias("orgid")
    private String orgId;

    /**
     * 通联商户号
     */
    @JsonAlias("cusid")
    private String cusId;

    /**
     * 通联AppID
     */
    private String appid;

    /**
     * 版本号（默认12）
     */
    private String version;

    @JsonAlias("randomstr")
    private String randomStr;

    /**
     * 交易金额（单位为分）
     */
    @JsonAlias("trxamt")
    private String trxAmt;

    /**
     * 商户交易单号（保证商户平台唯一） <br>
     * unireqsn与原订单号reqsn二选一 <br>
     * 当2个订单号并存时，优先取原reqsn的订单号原有逻辑。 <br>
     * reqsn订单号原有逻辑，同一订单号在微信/支付宝/云闪付等渠道可以同时存在下单。 <br>
     * unireqsn订单号新逻辑，同一订单号在微信/支付宝/云闪付渠道下单时系统会寻找当前商户其他相同unireqsn订单号的未支付的订单进行关单处理。
     */
    @JsonAlias("reqsn")
    private String reqSn;

    private String body;

    private String remark;

    @JsonAlias("expiretime")
    private String expireTime;

    @JsonAlias("appname")
    private String appName;

    /**
     * no_credit: 指定不能使用信用卡支付
     */
    @JsonAlias("limit_pay")
    private String limitPay;

    @JsonAlias("notify_url")
    private String notifyUrl;

    /**
     * 交易发起场景: 03 小程序 | 04 公众号
     */
    @JsonAlias("apptype")
    private String appType;

    @JsonAlias("cusip")
    private String cusIp;

    /**
     * 分账信息
     */
    @JsonAlias("asinfo")
    private String asInfo;

    /**
     * 签名方式 RSA | SM2
     */
    @JsonAlias("signtype")
    private String signType;

    private String sign;

    @JsonAlias("extendparams")
    private String extendParams;

    /**
     * 云闪付 - 支付参数构建
     *
     * @param trxAmt  金额
     * @param sn      订单号
     * @param body    商品描述
     * @param remark  备注
     * @param appid   TL AppId
     * @param cusId   TL 商户号
     * @param cusIp   TL 客户端IP
     * @param wxAppId 微信小程序ID
     * @param signKey 签名私钥
     * @throws Exception Exception
     */
    public void payInit(String orgId, long trxAmt, String sn, String body, String remark, String appid, String cusId, String cusIp, String wxAppId, String signKey, String callbackUrl) throws Exception {
        if(StrUtil.isNotEmpty(orgId)) {
            this.setOrgId(orgId);
        }
        this.setCusId(cusId);
        this.setAppid(appid);
        this.setVersion(SybConstants.SYB_YUN_PAY_VERSION);
        this.setRandomStr(SybUtil.getValidatecode(8));
        this.setTrxAmt(String.valueOf(trxAmt));
        this.setReqSn(sn);
        this.setBody(body);
        this.setRemark(remark);
        this.setExpireTime(LocalDateTime.now().plusMinutes(5).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        // 小程序id
        this.setAppName(wxAppId);
        this.setLimitPay("no_credit");
        this.setNotifyUrl(callbackUrl);
        this.setAppType("03");
        this.setCusIp(cusIp);
        this.setAsInfo("");
        this.setSignType(SybConstants.SIGN_TYPE);
        this.setExtendParams("");
        TreeMap<String, String> params = parseEntity(this);
        this.setSign(SybUtil.unionSign(params, signKey, SybConstants.SIGN_TYPE));
    }

    /**
     * 通联微信支付参数构建
     * @param trxAmt
     * @param sn
     * @param body
     * @param remark
     * @param appid
     * @param cusId
     * @param cusIp
     * @param wxAppId
     * @param signKey
     * @param callbackUrl
     * @throws Exception
     */
    public void wxPayInit(long trxAmt, String sn, String body, String remark, String appid, String cusId, String cusIp, String wxAppId, String signKey, String callbackUrl) throws Exception {
        this.setCusId(cusId);
        this.setAppid(appid);
        this.setVersion(SybConstants.SYB_YUN_PAY_VERSION);
        this.setRandomStr(SybUtil.getValidatecode(8));
        this.setTrxAmt(String.valueOf(trxAmt));
        this.setReqSn(sn);
        this.setBody(body);
        this.setRemark(remark);
        this.setExpireTime(LocalDateTime.now().plusHours(6).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        // 小程序id
        this.setAppName(wxAppId);
        this.setLimitPay("no_credit");
        this.setNotifyUrl(callbackUrl);
        this.setAppType("03");
        this.setCusIp(cusIp);
        this.setAsInfo("");
        this.setSignType(SybConstants.SIGN_TYPE);
        this.setExtendParams("");
        TreeMap<String, String> params = parseEntity(this);
        this.setSign(SybUtil.unionSign(params, signKey, SybConstants.SIGN_TYPE));
    }

}
